
#include <stdio.h>
#include "encoded-value.h"
#include "dex-structs.h"

int CDexEncodedValue::Size()
{
  int s=sizeof(ubyte);
	switch(value_type)
	{
	case VALUE_BYTE:
		s++;
	break;
	case VALUE_ARRAY:

		{
		  CDexEncodedArray *p=(CDexEncodedArray *)(this+1);
		  s+=p->Size();
		 }	
		
	break;
	case VALUE_ANNOTATION:

		{
		  CDexEncodedAnnotation *p=(CDexEncodedAnnotation *)(this+1);
		  s+=p->Size();
		 }	
		
	break;
	case VALUE_NULL:
	break;
	case VALUE_BOOLEAN:
	break;
	case VALUE_SHORT:
	case VALUE_CHAR:
	case VALUE_INT:
	case VALUE_LONG:
	case VALUE_FLOAT:
	case VALUE_DOUBLE:
	case VALUE_STRING:
	case VALUE_TYPE:
	case VALUE_FIELD:
	case VALUE_METHOD:
	case VALUE_ENUM:
		s+=value_arg;
	break;

  }
  return s;
}
	
	
void CDexEncodedValue::print()
{
  int j;


  
	switch(value_type)
	{
	case VALUE_BYTE:

        printf("%02x",((char *)(this+1))[0]);
		
	break;
	case VALUE_SHORT:

		{
         union
         {
           short v;
           char buf[1];
         }u;		
        char *t=(char*)(this+1);
        u.v=0;
        for(j=0;j<value_arg;j++) u.buf[j]=t[j];        
        
        printf("%04x",u.v);        
     }
   	
	break;
	case VALUE_CHAR:

		{
         union
         {
           short v;
           char buf[1];
         }u;		
        char *t=(char*)(this+1);
        u.v=0;
        for(j=0;j<value_arg;j++) u.buf[j]=t[j];        
        
        printf("%04x",u.v);        
     }
   	
	break;
	case VALUE_INT:

		{
         union
         {
           int v;
           char buf[1];
         }u;		
        char *t=(char*)(this+1);
        u.v=0;
        for(j=0;j<value_arg;j++) u.buf[j]=t[j];        
        
        printf("%08x",u.v);        
     }
   	
	break;
	case VALUE_LONG:

		{
         union
         {
           __int64 v;
           char buf[1];
         }u;		
        char *t=(char*)(this+1);
        u.v=0;
        for(j=0;j<value_arg;j++) u.buf[j]=t[j];        
        
        printf("%016x",u.v);        
     }
   	
	break;
	case VALUE_FLOAT:

		{
         union
         {
           float v;
           char buf[1];
         }u;		
        char *t=(char*)(this+1);
        u.v=0;
        for(j=0;j<value_arg;j++) u.buf[j]=t[j];        
        
        printf("%f",u.v);        
     }
   	
	break;
	case VALUE_DOUBLE:

		{
         union
         {
           double v;
           char buf[1];
         }u;		
        char *t=(char*)(this+1);
        u.v=0;
        for(j=0;j<value_arg;j++) u.buf[j]=t[j];        
        
        printf("%le",u.v);        
     }
   	
	break;
	case VALUE_STRING:

		{
         union
         {
           int v;
           char buf[1];
         }u;		
        char *t=(char*)(this+1);
        u.v=0;
        for(j=0;j<value_arg;j++) u.buf[j]=t[j];        
        
        printf("%08x",u.v);        
     }
   	
	break;
	case VALUE_TYPE:

		{
         union
         {
           int v;
           char buf[1];
         }u;		
        char *t=(char*)(this+1);
        u.v=0;
        for(j=0;j<value_arg;j++) u.buf[j]=t[j];        
        
        printf("%08x",u.v);        
     }
   	
	break;
	case VALUE_FIELD:

		{
         union
         {
           int v;
           char buf[1];
         }u;		
        char *t=(char*)(this+1);
        u.v=0;
        for(j=0;j<value_arg;j++) u.buf[j]=t[j];        
        
        printf("%08x",u.v);        
     }
   	
	break;
	case VALUE_METHOD:

		{
         union
         {
           int v;
           char buf[1];
         }u;		
        char *t=(char*)(this+1);
        u.v=0;
        for(j=0;j<value_arg;j++) u.buf[j]=t[j];        
        
        printf("%08x",u.v);        
     }
   	
	break;
	case VALUE_ENUM:

		{
         union
         {
           int v;
           char buf[1];
         }u;		
        char *t=(char*)(this+1);
        u.v=0;
        for(j=0;j<value_arg;j++) u.buf[j]=t[j];        
        
        printf("%08x",u.v);        
     }
   	
	break;
	case VALUE_ARRAY:

		{
		  CDexEncodedArray *p=(CDexEncodedArray *)(this+1);
		  p->print();
		 }	
		
	break;
	case VALUE_ANNOTATION:

		{
		  CDexEncodedAnnotation *p=(CDexEncodedAnnotation *)(this+1);
		  p->print();
		 }	
		
	break;
	case VALUE_NULL:
		printf("null");
	break;
	case VALUE_BOOLEAN:
		printf("%s",value_arg==1?"true":"false");
	break;

  }

}
	
	
int CDexEncodedValue::sprint(char * buffer)
{
  int j;
	int len=0;

  
	switch(value_type)
	{
	case VALUE_BYTE:

        len+=printf(buffer+len,"%02x",((char *)(this+1))[0]);
		
	break;
	case VALUE_SHORT:

		{
         union
         {
           short v;
           char buf[1];
         }u;		
        char *t=(char*)(this+1);
        u.v=0;
        for(j=0;j<value_arg;j++) u.buf[j]=t[j];                
        	len+=printf(buffer+len,"%04x",u.v);        
     }
   	
	break;
	case VALUE_CHAR:

		{
         union
         {
           short v;
           char buf[1];
         }u;		
        char *t=(char*)(this+1);
        u.v=0;
        for(j=0;j<value_arg;j++) u.buf[j]=t[j];                
        	len+=printf(buffer+len,"%04x",u.v);        
     }
   	
	break;
	case VALUE_INT:

		{
         union
         {
           int v;
           char buf[1];
         }u;		
        char *t=(char*)(this+1);
        u.v=0;
        for(j=0;j<value_arg;j++) u.buf[j]=t[j];                
        	len+=printf(buffer+len,"%08x",u.v);        
     }
   	
	break;
	case VALUE_LONG:

		{
         union
         {
           __int64 v;
           char buf[1];
         }u;		
        char *t=(char*)(this+1);
        u.v=0;
        for(j=0;j<value_arg;j++) u.buf[j]=t[j];                
        	len+=printf(buffer+len,"%016x",u.v);        
     }
   	
	break;
	case VALUE_FLOAT:

		{
         union
         {
           float v;
           char buf[1];
         }u;		
        char *t=(char*)(this+1);
        u.v=0;
        for(j=0;j<value_arg;j++) u.buf[j]=t[j];                
        	len+=printf(buffer+len,"%f",u.v);        
     }
   	
	break;
	case VALUE_DOUBLE:

		{
         union
         {
           double v;
           char buf[1];
         }u;		
        char *t=(char*)(this+1);
        u.v=0;
        for(j=0;j<value_arg;j++) u.buf[j]=t[j];                
        	len+=printf(buffer+len,"%le",u.v);        
     }
   	
	break;
	case VALUE_STRING:

		{
         union
         {
           int v;
           char buf[1];
         }u;		
        char *t=(char*)(this+1);
        u.v=0;
        for(j=0;j<value_arg;j++) u.buf[j]=t[j];                
        	len+=printf(buffer+len,"%08x",u.v);        
     }
   	
	break;
	case VALUE_TYPE:

		{
         union
         {
           int v;
           char buf[1];
         }u;		
        char *t=(char*)(this+1);
        u.v=0;
        for(j=0;j<value_arg;j++) u.buf[j]=t[j];                
        	len+=printf(buffer+len,"%08x",u.v);        
     }
   	
	break;
	case VALUE_FIELD:

		{
         union
         {
           int v;
           char buf[1];
         }u;		
        char *t=(char*)(this+1);
        u.v=0;
        for(j=0;j<value_arg;j++) u.buf[j]=t[j];                
        	len+=printf(buffer+len,"%08x",u.v);        
     }
   	
	break;
	case VALUE_METHOD:

		{
         union
         {
           int v;
           char buf[1];
         }u;		
        char *t=(char*)(this+1);
        u.v=0;
        for(j=0;j<value_arg;j++) u.buf[j]=t[j];                
        	len+=printf(buffer+len,"%08x",u.v);        
     }
   	
	break;
	case VALUE_ENUM:

		{
         union
         {
           int v;
           char buf[1];
         }u;		
        char *t=(char*)(this+1);
        u.v=0;
        for(j=0;j<value_arg;j++) u.buf[j]=t[j];                
        	len+=printf(buffer+len,"%08x",u.v);        
     }
   	
	break;
	case VALUE_ARRAY:

		{
		  CDexEncodedArray *p=(CDexEncodedArray *)(this+1);
		  len+=p->sprint(buffer+len);
		 }	
		
	break;
	case VALUE_ANNOTATION:

		{
		  CDexEncodedAnnotation *p=(CDexEncodedAnnotation *)(this+1);
		  len+=p->sprint(buffer+len);
		 }	
		
	break;
	case VALUE_NULL:
		len+=printf(buffer+len,"null");
	break;
	case VALUE_BOOLEAN:
		len+=printf(buffer+len,"%s",value_arg==1?"true":"false");
	break;

  }
  return len;

}
	
